﻿using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Services.Store;
using Windows.System;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;

namespace Wino.Core.UWP.Services;

public class StoreRatingService : IStoreRatingService
{
    private const string RatedStorageKey = nameof(RatedStorageKey);
    private const string LatestAskedKey = nameof(LatestAskedKey);

    private readonly IConfigurationService _configurationService;
    private readonly IMailDialogService _dialogService;

    public StoreRatingService(IConfigurationService configurationService, IMailDialogService dialogService)
    {
        _configurationService = configurationService;
        _dialogService = dialogService;
    }

    private bool IsAskingThresholdExceeded()
    {
        var latestAskedDate = _configurationService.Get(LatestAskedKey, DateTime.MinValue);

        // Never asked before.
        // Set the threshold and wait for the next trigger.

        if (latestAskedDate == DateTime.MinValue)
        {
            _configurationService.Set(LatestAskedKey, DateTime.UtcNow);
        }
        else if (DateTime.UtcNow >= latestAskedDate.AddMinutes(30))
        {
            return true;
        }

        return false;
    }

    public async Task PromptRatingDialogAsync()
    {
        // Annoying.
        if (Debugger.IsAttached) return;

        // Swallow all exceptions. App should not crash in any errors.

        try
        {
            bool isRated = _configurationService.GetRoaming(RatedStorageKey, false);

            if (isRated) return;

            if (!isRated)
            {
                if (!IsAskingThresholdExceeded()) return;

                var isRateWinoApproved = await _dialogService.ShowWinoCustomMessageDialogAsync(Translator.StoreRatingDialog_Title,
                    Translator.StoreRatingDialog_MessageFirstLine,
                    Translator.Buttons_RateWino,
                    Domain.Enums.WinoCustomMessageDialogIcon.Question,
                    Translator.Buttons_No,
                    RatedStorageKey);

                if (isRateWinoApproved)
                {
                    // In case of failure of this call, we will navigate users to Store page directly.

                    try
                    {
                        await ShowPortableRatingDialogAsync();
                    }
                    catch (Exception)
                    {
                        await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
                    }
                }
            }
        }
        catch (Exception) { }
        finally
        {
            _configurationService.Set(LatestAskedKey, DateTime.UtcNow);
        }
    }

    private async Task ShowPortableRatingDialogAsync()
    {
        var _storeContext = StoreContext.GetDefault();

        StoreRateAndReviewResult result = await _storeContext.RequestRateAndReviewAppAsync();

        // Check status
        switch (result.Status)
        {
            case StoreRateAndReviewStatus.Succeeded:
                if (result.WasUpdated)
                    _dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewUpdatedMessage, Domain.Enums.InfoBarMessageType.Success);
                else
                    _dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewNewMessage, Domain.Enums.InfoBarMessageType.Success);

                _configurationService.Set(RatedStorageKey, true);
                break;
            case StoreRateAndReviewStatus.CanceledByUser:
                break;

            case StoreRateAndReviewStatus.NetworkError:
                _dialogService.InfoBarMessage(Translator.Info_ReviewNetworkErrorTitle, Translator.Info_ReviewNetworkErrorMessage, Domain.Enums.InfoBarMessageType.Warning);
                break;
            default:
                _dialogService.InfoBarMessage(Translator.Info_ReviewUnknownErrorTitle, string.Format(Translator.Info_ReviewUnknownErrorMessage, result.ExtendedError.Message), Domain.Enums.InfoBarMessageType.Warning);
                break;
        }
    }

    public async Task LaunchStorePageForReviewAsync()
    {
        try
        {
            await CoreApplication.GetCurrentView()?.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
            {
                // TODO: Get it from package info.
                await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
            });
        }
        catch (Exception) { }
    }
}
